home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / machine / tait8741.c < prev    next >
C/C++ Source or Header  |  2000-04-23  |  8KB  |  361 lines

  1. /*
  2. Taito 8741 emulation
  3.  
  4. 1.comminucation main and sub cpu
  5. 2.dipswitch and key handling
  6.  
  7. program types
  8.  
  9. */
  10.  
  11. #include "driver.h"
  12. #include "tait8741.h"
  13.  
  14. //#define __log__ 1
  15.  
  16. #define CMD_IDLE 0
  17. #define CMD_08 1
  18. #define CMD_4a 2
  19.  
  20. typedef struct TAITO8741_status{
  21.     unsigned char toData;    /* to host data      */
  22.     unsigned char fromData;  /* from host data    */
  23.     unsigned char fromCmd;   /* from host command */
  24.     unsigned char status;    /* b0 = rd ready,b1 = wd full,b2 = cmd ?? */
  25.     unsigned char mode;
  26.     unsigned char phase;
  27.     unsigned char txd[8];
  28.     unsigned char rxd[8];
  29.     unsigned char parallelselect;
  30.     unsigned char txpoint;
  31.     int connect;
  32.     unsigned char pending4a;
  33.     int serial_out;
  34.     int coins;
  35.     mem_read_handler portHandler;
  36. }I8741;
  37.  
  38. static const struct TAITO8741interface *intf;
  39. //static I8741 *taito8741;
  40. static I8741 taito8741[MAX_TAITO8741];
  41.  
  42. /* for host data , write */
  43. static void taito8741_hostdata_w(I8741 *st,int data)
  44. {
  45.     st->toData = data;
  46.     st->status |= 0x01;
  47. }
  48.  
  49. /* from host data , read */
  50. static int taito8741_hostdata_r(I8741 *st)
  51. {
  52.     if( !(st->status & 0x02) ) return -1;
  53.     st->status &= 0xfd;
  54.     return st->fromData;
  55. }
  56.  
  57. /* from host command , read */
  58. static int taito8741_hostcmd_r(I8741 *st)
  59. {
  60.     if(!(st->status & 0x04)) return -1;
  61.     st->status &= 0xfb;
  62.     return st->fromCmd;
  63. }
  64.  
  65.  
  66. /* TAITO8741 I8741 emulation */
  67.  
  68. void taito8741_serial_rx(I8741 *st,unsigned char *data)
  69. {
  70.     memcpy(st->rxd,data,8);
  71. }
  72.  
  73. /* timer callback of serial tx finish */
  74. void taito8741_serial_tx(int num)
  75. {
  76.     I8741 *st = &taito8741[num];
  77.     I8741 *sst;
  78.  
  79.     if( st->mode==TAITO8741_MASTER)
  80.         st->serial_out = 1;
  81.  
  82.     st->txpoint = 1;
  83.     if(st->connect >= 0 )
  84.     {
  85.         sst = &taito8741[st->connect];
  86.         /* transfer data */
  87.         taito8741_serial_rx(sst,st->txd);
  88. #if __log__
  89.         logerror("8741-%d Serial data TX to %d\n",num,st->connect);
  90. #endif
  91.         if( sst->mode==TAITO8741_SLAVE)
  92.             sst->serial_out = 1;
  93.     }
  94. }
  95.  
  96. void TAITO8741_reset(int num)
  97. {
  98.     I8741 *st = &taito8741[num];
  99.     st->status = 0x00;
  100.     st->phase = 0;
  101.     st->parallelselect = 0;
  102.     st->txpoint = 1;
  103.     st->pending4a = 0;
  104.     st->serial_out = 0;
  105.     st->coins = 0;
  106.     memset(st->rxd,0,8);
  107.     memset(st->txd,0,8);
  108. }
  109.  
  110. /* 8741 update */
  111. static void taito8741_update(int num)
  112. {
  113.     I8741 *st,*sst;
  114.     int next = num;
  115.     int data;
  116.  
  117.     do{
  118.         num = next;
  119.         st = &taito8741[num];
  120.         if( st->connect != -1 )
  121.              sst = &taito8741[st->connect];
  122.         else sst = 0;
  123.         next = -1;
  124.         /* check pending command */
  125.         switch(st->phase)
  126.         {
  127.         case CMD_08: /* serial data latch */
  128.             if( st->serial_out)
  129.             {
  130.                 st->status &= 0xfb; /* patch for gsword */
  131.                 st->phase = CMD_IDLE;
  132.                 next = num; /* continue this chip */
  133.             }
  134.             break;
  135.         case CMD_4a: /* wait for syncronus ? */
  136.             if(!st->pending4a)
  137.             {
  138.                 taito8741_hostdata_w(st,0);
  139.                 st->phase = CMD_IDLE;
  140.                 next = num; /* continue this chip */
  141.             }
  142.             break;
  143.         case CMD_IDLE:
  144.             /* ----- data in port check ----- */
  145.             data = taito8741_hostdata_r(st);
  146.             if( data != -1 )
  147.             {
  148.                 switch(st->mode)
  149.                 {
  150.                 case TAITO8741_MASTER:
  151.                 case TAITO8741_SLAVE:
  152.                     /* buffering transmit data */
  153.                     if( st->txpoint < 8 )
  154.                     {
  155. //if (st->txpoint == 0 && num==1 && data&0x80) logerror("Coin Put\n");
  156.                         st->txd[st->txpoint++] = data;
  157.                     }
  158.                     break;
  159.                 case TAITO8741_PORT:
  160.                     if( data & 0xf8)
  161.                     { /* ?? */
  162.                     }
  163.                     else
  164.                     { /* port select */
  165.                         st->parallelselect = data & 0x07;
  166.                         taito8741_hostdata_w(st,st->portHandler ? st->portHandler(st->parallelselect) : 0);
  167.                     }
  168.                 }
  169.             }
  170.             /* ----- new command fetch ----- */
  171.             data = taito8741_hostcmd_r(st);
  172.             switch( data )
  173.             {
  174.             case -1: /* no command data */
  175.                 break;
  176.             case 0x00: /* read from parallel port */
  177.                 taito8741_hostdata_w(st,st->portHandler ? st->portHandler(0) : 0 );
  178.                 break;
  179.             case 0x01: /* read receive buffer 0 */
  180.             case 0x02: /* read receive buffer 1 */
  181.             case 0x03: /* read receive buffer 2 */
  182.             case 0x04: /* read receive buffer 3 */
  183.             case 0x05: /* read receive buffer 4 */
  184.             case 0x06: /* read receive buffer 5 */
  185.             case 0x07: /* read receive buffer 6 */
  186. //if (data == 2 && num==0 && st->rxd[data-1]&0x80) logerror("Coin Get\n");
  187.                 taito8741_hostdata_w(st,st->rxd[data-1]);
  188.                 break;
  189.             case 0x08:    /* latch received serial data */
  190.                 st->txd[0] = st->portHandler ? st->portHandler(0) : 0;
  191.                 if( sst )
  192.                 {
  193.                     timer_set (TIME_NOW,num,taito8741_serial_tx);
  194.                     st->serial_out = 0;
  195.                     st->status |= 0x04;
  196.                     st->phase = CMD_08;
  197.                 }
  198.                 break;
  199.             case 0x0a:    /* 8741-0 : set serial comminucation mode 'MASTER' */
  200.                 //st->mode = TAITO8741_MASTER;
  201.                 break;
  202.             case 0x0b:    /* 8741-1 : set serial comminucation mode 'SLAVE'  */
  203.                 //st->mode = TAITO8741_SLAVE;
  204.                 break;
  205.             case 0x1f:  /* 8741-2,3 : ?? set parallelport mode ?? */
  206.             case 0x3f:  /* 8741-2,3 : ?? set parallelport mode ?? */
  207.             case 0xe1:  /* 8741-2,3 : ?? set parallelport mode ?? */
  208.                 st->mode = TAITO8741_PORT;
  209.                 st->parallelselect = 1; /* preset read number */
  210.                 break;
  211.             case 0x62:  /* 8741-3   : ? */
  212.                 break;
  213.             case 0x4a:    /* ?? syncronus with other cpu and return 00H */
  214.                 if( sst )
  215.                 {
  216.                     if(sst->pending4a)
  217.                     {
  218.                         sst->pending4a = 0; /* syncronus */
  219.                         taito8741_hostdata_w(st,0); /* return for host */
  220.                         next = st->connect;
  221.                     }
  222.                     else st->phase = CMD_4a;
  223.                 }
  224.                 break;
  225.             case 0x80:    /* 8741-3 : return check code */
  226.                 taito8741_hostdata_w(st,0x66);
  227.                 break;
  228.             case 0x81:    /* 8741-2 : return check code */
  229.                 taito8741_hostdata_w(st,0x48);
  230.                 break;
  231.             case 0xf0:  /* GSWORD 8741-1 : initialize ?? */
  232.                 break;
  233.             case 0x82:  /* GSWORD 8741-2 unknown */
  234.                 break;
  235.             }
  236.             break;
  237.         }
  238.     }while(next>=0);
  239. }
  240.  
  241. int TAITO8741_start(const struct TAITO8741interface *taito8741intf)
  242. {
  243.     int i;
  244.  
  245.     intf = taito8741intf;
  246.  
  247.     //taito8741 = (I8741 *)malloc(intf->num*sizeof(I8741));
  248.     //if( taito8741 == 0 ) return 1;
  249.  
  250.     for(i=0;i<intf->num;i++)
  251.     {
  252.         taito8741[i].connect     = intf->serial_connect[i];
  253.         taito8741[i].portHandler = intf->portHandler_r[i];
  254.         taito8741[i].mode        = intf->mode[i];
  255.         TAITO8741_reset(i);
  256.     }
  257.     return 0;
  258. }
  259.  
  260. /* read status port */
  261. static int I8741_status_r(int num)
  262. {
  263.     I8741 *st = &taito8741[num];
  264.     taito8741_update(num);
  265. #if __log__
  266.     logerror("8741-%d ST Read %02x PC=%04x\n",num,st->status,cpu_get_pc());
  267. #endif
  268.     return st->status;
  269. }
  270.  
  271. /* read data port */
  272. static int I8741_data_r(int num)
  273. {
  274.     I8741 *st = &taito8741[num];
  275.     int ret = st->toData;
  276.     st->status &= 0xfe;
  277. #if __log__
  278.     logerror("8741-%d DATA Read %02x PC=%04x\n",num,ret,cpu_get_pc());
  279. #endif
  280.     /* update chip */
  281.     taito8741_update(num);
  282.  
  283.     switch( st->mode )
  284.     {
  285.     case TAITO8741_PORT: /* parallel data */
  286.         taito8741_hostdata_w(st,st->portHandler ? st->portHandler(st->parallelselect) : 0);
  287.         break;
  288.     }
  289.     return ret;
  290. }
  291.  
  292. /* Write data port */
  293. static void I8741_data_w(int num, int data)
  294. {
  295.     I8741 *st = &taito8741[num];
  296. #if __log__
  297.     logerror("8741-%d DATA Write %02x PC=%04x\n",num,data,cpu_get_pc());
  298. #endif
  299.     st->fromData = data;
  300.     st->status |= 0x02;
  301.     /* update chip */
  302.     taito8741_update(num);
  303. }
  304.  
  305. /* Write command port */
  306. static void I8741_command_w(int num, int data)
  307. {
  308.     I8741 *st = &taito8741[num];
  309. #if __log__
  310.     logerror("8741-%d CMD Write %02x PC=%04x\n",num,data,cpu_get_pc());
  311. #endif
  312.     st->fromCmd = data;
  313.     st->status |= 0x04;
  314.     /* update chip */
  315.     taito8741_update(num);
  316. }
  317.  
  318. /* Write port handler */
  319. WRITE_HANDLER( TAITO8741_0_w )
  320. {
  321.     if(offset&1) I8741_command_w(0,data);
  322.     else         I8741_data_w(0,data);
  323. }
  324. WRITE_HANDLER( TAITO8741_1_w )
  325. {
  326.     if(offset&1) I8741_command_w(1,data);
  327.     else         I8741_data_w(1,data);
  328. }
  329. WRITE_HANDLER( TAITO8741_2_w )
  330. {
  331.     if(offset&1) I8741_command_w(2,data);
  332.     else         I8741_data_w(2,data);
  333. }
  334. WRITE_HANDLER( TAITO8741_3_w )
  335. {
  336.     if(offset&1) I8741_command_w(3,data);
  337.     else         I8741_data_w(3,data);
  338. }
  339.  
  340. /* Read port handler */
  341. READ_HANDLER( TAITO8741_0_r )
  342. {
  343.     if(offset&1) return I8741_status_r(0);
  344.     return I8741_data_r(0);
  345. }
  346. READ_HANDLER( TAITO8741_1_r )
  347. {
  348.     if(offset&1) return I8741_status_r(1);
  349.     return I8741_data_r(1);
  350. }
  351. READ_HANDLER( TAITO8741_2_r )
  352. {
  353.     if(offset&1) return I8741_status_r(2);
  354.     return I8741_data_r(2);
  355. }
  356. READ_HANDLER( TAITO8741_3_r )
  357. {
  358.     if(offset&1) return I8741_status_r(3);
  359.     return I8741_data_r(3);
  360. }
  361.